#include "Task.hpp"
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>

using namespace std;

const int processnum =4;
vector<task_t> tasks; //把所有的任务，装进去

class channel
{
   public:
    channel(int &cmdfd ,int &mypid,string &name)
    :_name(name)
    ,_cmdfd(cmdfd)
    ,_mypid(mypid)
    {}
   public:
    string _name;//子进程的名字
    int _cmdfd;//发信号的文件描述符  
    int _mypid;//我的PID
};

void Menu()
{
    std::cout << "################################################" << std::endl;
    std::cout << "# 1. 刷新日志             2. 刷新出来野怪        #" << std::endl;
    std::cout << "# 3. 检测软件是否更新      4. 更新用的血量和蓝量  #" << std::endl;
    std::cout << "#                         0. 退出               #" << std::endl;
    std::cout << "#################################################" << std::endl;
}

void slaver(int pool)
{
    while(true)
    {
        int cmdcode=0;//通过调用码，去领任务
        int n=read(pool,&cmdcode,sizeof(int));
        cout <<"slaver say@ get a command: "<< getpid() << " : cmdcode: " <<  cmdcode << endl;
        if(cmdcode>0&&cmdcode<=tasks.size()) tasks[cmdcode-1]();
        if(n==0) break;
        
    }
}

void InitProcesspool(vector<channel>&channels)
{
     vector<int> d;//把父进程的所有打开的写管道存储到里面
     for(int i=1;i<=processnum;i++)
     {
        int pipeid[2];
        int n=pipe(pipeid);
        assert(!n);

        int pid=fork();
        if(pid==0)
        {
        cout<<"创建的"<< i<<"号子进程"<<endl;
          for(auto &t:d)
          {
            close(t);//关掉所有不相关的管道
          }
          close(pipeid[1]);//关闭写管道

          slaver(pipeid[0]);//读操作
        // close(pipeid[0]);//多此一举
        cout<<"关闭的"<< i<<"号子进程"<<endl;
          exit(0);
        }

        close(pipeid[0]);
        string name="创建的子进程"+to_string(i);
        channels.push_back({pipeid[1],pid,name});//那个管道发数据记录下来，
        d.push_back(pipeid[1]);//把一会发数据的管道号记下来
        sleep(1);
     }
}



void setslaver(vector<channel>&channels)
{
    int which=0;
    int cnt=4;
    while(cnt--)
    {
        int slect=0;
        Menu();
        cin>>slect;     
        if(!slect) break;   
        // rand((void)time(nullptr));
        // int i=srand()%5;
        cout<<"farher message"<<channels[which]._name<<endl;
        write(channels[which]._cmdfd,&slect,sizeof(int));     
        which++;
        which%=channels.size();

        sleep(1);
    }
}

void Quitpool(vector<channel>&channels)
{
    for(auto& t:channels)//关闭所有的写管道
    {
    close(t._cmdfd);
    waitpid(t._mypid,nullptr,0);
    }
}

int main()
{
    vector<channel> channels;//把打开的子进程装进来
    LoadTask(tasks);
    InitProcesspool(channels);//创建子进程
    
    setslaver(channels);//发配任务，采用轮询

    Quitpool(channels);//关闭写管道，等到read=0子进程退出，全部关闭

    return 0;
}
